`include "def.h"
module decode(
input [`OPCODE_W-1:0] opcode, 
input [`OPCODE_W-1:0] func, 
input zero, mi,
output [1:0] alu_bsel, comsel, rf_csel, 
output pcsel, we, rwe, casel, pcjr);

wire st_op, bez_op, bnz_op, bmi_op, bpl_op, addi_op, ld_op, alu_op;
wire ldi_op, ldiu_op, ldhi_op, addiu_op, jmp_op, jal_op, jr_op, jalr_op;

assign st_op = (opcode == `OP_REG) & (func == `F_ST);
assign ld_op = (opcode == `OP_REG) & (func == `F_LD);
assign jr_op = (opcode == `OP_REG) & (func == `F_JR);
assign jalr_op = (opcode == `OP_REG) & (func == `F_JALR);
assign alu_op = (opcode == `OP_REG) & (func[4:3] == 2'b00);
assign ldi_op = (opcode == `OP_LDI);
assign ldiu_op = (opcode == `OP_LDIU);
assign addi_op = (opcode == `OP_ADDI);
assign addiu_op = (opcode == `OP_ADDIU);
assign ldhi_op = (opcode == `OP_LDHI);
assign bez_op = (opcode == `OP_BEZ);
assign bnz_op = (opcode == `OP_BNZ);
assign bpl_op = (opcode == `OP_BPL);
assign bmi_op = (opcode == `OP_BMI);
assign jmp_op = (opcode == `OP_JMP);
assign jal_op = (opcode == `OP_JAL);

assign we = st_op;
assign rwe =  ld_op  | alu_op | ldi_op | ldiu_op | addi_op | addiu_op | ldhi_op
                | jal_op ;
assign rf_csel = ld_op ? 01 : jal_op ? 10: 00 ;
assign alu_bsel = (addi_op | ldi_op) ? 01 : 
			(addiu_op | ldiu_op) ? 10 :
			ldhi_op? 11 : 00;
assign comsel = (addi_op | addiu_op) ? 01 : 
			(ldi_op | ldiu_op | ldhi_op) ? 10 : 00;
assign casel = jal_op;
assign pcjr = jr_op;
assign pcsel = (bez_op & zero | bnz_op & ~zero | 
		bpl_op & ~mi | bmi_op & mi) ? 01 :
		jmp_op & jal_op ? 10 : 00;
		
endmodule	
